﻿using SuperX.Common;
using SuperX.Common.Abstract;
using SuperX.Common.Collection;
using HslCommunication.Core;
using HslCommunication.Core.Net;
using HslCommunication.Serial;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Text;

namespace SuperX.DataService.Abstract
{
    public interface IReaderWriter
    {
        byte[] ReadBytes(DeviceAddress address, ushort size);

        bool[] ReadBools(DeviceAddress address, ushort size);

        ItemData<uint> ReadUInt32(DeviceAddress address);

        ItemData<int> ReadInt32(DeviceAddress address);

        ItemData<ushort> ReadUInt16(DeviceAddress address);

        ItemData<short> ReadInt16(DeviceAddress address);

        ItemData<byte> ReadByte(DeviceAddress address);

        ItemData<string> ReadString(DeviceAddress address, ushort size);

        ItemData<float> ReadFloat(DeviceAddress address);

        ItemData<bool> ReadBit(DeviceAddress address);

        ItemData<dynamic> ReadDynamic(DeviceAddress address);

        int WriteBytes(DeviceAddress address, byte[] bit);

        int WriteBit(DeviceAddress address, bool bit);

        int WriteBits(DeviceAddress address, byte bits);

        int WriteInt16(DeviceAddress address, short value);

        int WriteUInt16(DeviceAddress address, ushort value);

        int WriteInt32(DeviceAddress address, int value);

        int WriteUInt32(DeviceAddress address, uint value);

        int WriteFloat(DeviceAddress address, float value);

        int WriteString(DeviceAddress address, string str);

        int WriteDynamic(IIOTag tag, object value);
    }

    public interface ICache : IReaderWriter
    {
        int Size { get; set; }
        int ByteCount { get; }
        Array Cache { get; }

        int GetOffset(DeviceAddress start, DeviceAddress end);
    }

    public interface IMultiReadWrite
    {
        int Limit { get; }
    }

    public delegate void ClosedChangedEventHandler(object sender, EventArgs e);

    public interface IDriver : IObjCollection, IDisposable
    {
        event ClosedChangedEventHandler ClosedChanged;

        bool Enabled { get; set; }
        string DriverNO { get; set; }
        short ID { get; }
        string ServerName { get; set; }//可以考虑增加一个附加参数，Sever只定义本机名
        bool IsClosed { get; }
        int TimeOut { get; set; }
        IEnumerable<IGroup> Groups { get; }
        IDataServer DriverParent { get; }

        bool Connect();

        IGroup AddGroup(string name, int updateRate, float deadBand = 0f, bool active = false);

        bool RemoveGroup(IGroup group);

        event IOErrorEventHandler OnError;

        DateTime ExpiryTime { get; set; }

        string NodeKey { get; set; }

        /// <summary>
        /// 配置的名称
        /// </summary>
        string ConfigName { get; set; }
    }

    /// <summary>
    /// 虚拟设备，用于文件分析，只读设备
    /// </summary>
    public interface IVirtualDriver : IDriver, IReaderWriter
    {
        bool Init();

        void UpdateIOTag(string groupName);
    }

    /// <summary>
    /// 实体设备，有反控功能的
    /// </summary>
    public interface IReallDriver : IDriver, IReaderWriter
    {
        bool Init();

        void UpdateIOTag(string groupName);
    }

    public interface IApiDriver : IDriver, IReaderWriter
    {
        void DeviceApi(JObject parameter);
    }

    public interface IPLCDriver : IDriver, IReaderWriter
    {
        int PDU { get; }

        DeviceAddress GetDeviceAddress(TagConfig meta);

        string GetAddress(DeviceAddress address);

        IByteTransform ByteTransform { get; }

        IReadWriteNet ReadWriteNet { get; }
    }

    public interface IFileDriver : IVirtualDriver, IReaderWriter
    {
        string FileName { get; set; }

        FileData[] ReadAll(string groupName);

        List<FileData[]> ReadToList(string groupName);

        //bool RecieveData(string data);
    }

    public interface IScanFileDriver : IFileDriver
    {
        List<FileAnalysisConfig> FileAnalysis { get; set; }

        void Scan();

        string GetLogPath();
    }

    public class IOErrorEventArgs : EventArgs
    {
        public IOErrorEventArgs(string reson)
        {
            Reason = reson;
        }

        public string Reason;
    }

    public delegate void IOErrorEventHandler(object sender, IOErrorEventArgs e);
}